package cn.falcon.fmobi.console.controller;

import cn.falcon.fmobi.biz.common.Constant;
import cn.falcon.fmobi.biz.exception.AudienceValidateException;
import cn.falcon.fmobi.biz.service.*;
import cn.falcon.fmobi.console.common.RestfulJsonModelAndView;
import cn.falcon.fmobi.console.common.Result;
import cn.falcon.fmobi.console.constant.ParamConstant;
import cn.falcon.fmobi.console.constant.UrlConstant;
import cn.falcon.fmobi.console.exception.CallBackException;
import cn.falcon.fmobi.console.exception.ParamValidateException;
import cn.falcon.fmobi.console.requestparam.AudienceQuery;
import cn.falcon.fmobi.dao.enumration.NumberType;
import cn.falcon.fmobi.dao.enumration.UploadResourceType;
import cn.falcon.fmobi.dao.model.*;
import cn.falcon.fmobi.dao.po.AdvertiserPlatformAudit;
import cn.falcon.fmobi.dao.po.UploadResource;
import cn.falcon.fmobi.dao.util.UploadMD5Util;
import cn.falcon.marketing.api.util.ValidateUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpSession;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.*;

/**
 * Created by haojie.zhang
 * Time 2017/9/21.
 */

@Controller
@RequestMapping(UrlConstant.AUDIENCE_URL)
public class AudienceCtrl extends BaseCtrl{

    @Value("${upload.dir}")
    private String resourceAddress;

    @Value("${res.url.path}")
    private String serverAddress;

    @Value("${accountId}")
    private String accountId;

    @Autowired
    private AudienceService audienceService;

    @Autowired
    private AudienceLikeService audienceLikeService;

    @Autowired
    private TargetPackageService targetPackageService;

    @Autowired
    private AdvertiserPlatformAuditService advertiserPlatformAuditService;

    @Autowired
    private UploadResourceService uploadResourceService;

    /**
     * 自定义人群列表
     * @param
     * @return
     */
    @RequestMapping(value = "/audienceFileList", method = {RequestMethod.GET})
    public ModelAndView audienceFileList(HttpSession session){
        Integer advertiserId = getLoginUser(session) != null ? getLoginUser(session).getAdvertiserId() : null;
        // 查询代理商id
        Integer agentId = getLoginUser(session) != null ? getLoginUser(session).getAgentId() : null;
        Map<String, Object> param = new HashMap<>();
        param.put("advertiserId", advertiserId);
        param.put("agentId", agentId);
        List<AudienceFileModel> audienceFileModelList = audienceService.audienceFileList(param);
        return RestfulJsonModelAndView.buildJsonModelAndView(audienceFileModelList);
    }

    /**
     * 相似人群详情
     * @param id
     * @return
     */
    @RequestMapping(value = "/getAudienceLike", method = {RequestMethod.GET})
    public ModelAndView getAudienceLike(@RequestParam int id){
        AudienceGetLikeModel audienceGetLikeModel = audienceService.AudienceLikeGet(id);
        return RestfulJsonModelAndView.buildJsonModelAndView(audienceGetLikeModel);
    }

    /**
     * 模糊查询接口（自定义人群，相似人群）
     *
     * @param
     * @return
     */
    @RequestMapping(value = "/listAudience",method = {RequestMethod.GET})
    public ModelAndView listAudience(AudienceQuery AudienceQuery,HttpSession session) {
        Map<String, Object> param = AudienceQuery.getSearch();

        Integer advertiserId = getLoginUser(session) != null ? getLoginUser(session).getAdvertiserId() : null;
        // 查询代理商id
        Integer agentId = getLoginUser(session) != null ? getLoginUser(session).getAgentId() : null;
        param.put("advertiserId",null == advertiserId ? AudienceQuery.getAdveristerId() : advertiserId);
        param.put("agentId", agentId);
        return RestfulJsonModelAndView.buildJsonModelAndView(audienceService.listAudience(param,AudienceQuery.getPageInfo()));
    }

    /**
     * 更新人群接口（自定义人群，相似人群）
     *
     * @param updateAudienceVo
     * @return
     */
    @RequestMapping(value = "/updateAudience", method = {RequestMethod.PUT})
    public ModelAndView updateAudience(@RequestBody UpdateAudienceVo updateAudienceVo) throws ParamValidateException, UnsupportedEncodingException {
        MarketingIdModel marketingAudience = audienceService.getMarketingAudienceId(updateAudienceVo.getId());
        updateAudienceVo.setMarketingAudienceId(marketingAudience.getMarketingAudienceId());
        updateAudienceVo.setAccountId(Integer.parseInt(accountId));
        updateAudienceVo.setAdvertiserId(marketingAudience.getAdvertiserId());
        this.checkUpdate(updateAudienceVo);
        audienceService.updateAudience(updateAudienceVo);
        return RestfulJsonModelAndView.buildJsonModelAndView();
    }

    /**
     * update验证
     *
     * @param updateAudienceVo
     */
    public void checkUpdate(UpdateAudienceVo updateAudienceVo) throws ParamValidateException, UnsupportedEncodingException {

        int count = audienceService.countName(updateAudienceVo.getName(), updateAudienceVo.getAdvertiserId(),updateAudienceVo.getId());
        if (count != 0) {
            throw new CallBackException(AudienceValidateException.ErrorCode.AUDIENCE_NAME_NOT_NULL.getValue()
                    , AudienceValidateException.ErrorCode.AUDIENCE_NAME_NOT_NULL.getDesc());
        }
        //人群名称必填
        if(StringUtils.isEmpty(updateAudienceVo.getName())){
            throw new ParamValidateException(Result.ERR_MISS_PARAMETER, "crowdName", "Result.err.miss.parameter");
        }
        //名称长度限制
        if (ValidateUtil.checkStrByteLengthLessThan(updateAudienceVo.getName(), ParamConstant.CROWD_NAME_LENGTH_MIN)
                || ValidateUtil.checkStrByteLengthMoreThan(updateAudienceVo.getName(), ParamConstant.CROWD_NAME_LENGTH_MAX)) {
            throw new ParamValidateException(Result.ERR_INVALID_LENGTH, "crowdName", "Result.err.invalid.length");
        }
        //描述最大长度
        if (ValidateUtil.checkStrByteLengthMoreThan(updateAudienceVo.getDescription(),ParamConstant.CROWD_DESCRIPTION_LENGTH_MAX)){
            throw new ParamValidateException(Result.ERR_INVALID_LENGTH, "crowdDescription", "Result.err.invalid.length");
        }

    }
    /**
     * 人群详情
     * @param id
     * @return
     */
    @RequestMapping(value = "/getAudienceFile", method = {RequestMethod.GET})
    public ModelAndView getAudienceFile(@RequestParam int id){
        AudienceGetModel audienceGetModel = audienceService.AudienceGet(id);
        return RestfulJsonModelAndView.buildJsonModelAndView(audienceGetModel);
    }

    /**
     * 包类型
     * @return
     */
    @RequestMapping("/numberType")
    public ModelAndView numberType(){
        List<NumberTypeModel>param=new ArrayList<>();
        NumberTypeModel numberTypeModel;
        for (NumberType numberType : NumberType.values()) {
            numberTypeModel= new NumberTypeModel();
            numberTypeModel.setName(numberType.getName());
            numberTypeModel.setId(numberType.getValue());
            param.add(numberTypeModel);
        }
        return RestfulJsonModelAndView.buildJsonModelAndView(param);
    }
    /**
     * 文件上传
     * @return
     * @throws IOException
     */
    @RequestMapping("/fileUpload")
    public ModelAndView fileUpload(@RequestParam("file") MultipartFile[] goodsPics) {
        String fileName = UUID.randomUUID() + ".zip";
        String path = resourceAddress;
        String relativePath = serverAddress + "/" + fileName;
        File file = new File(path, fileName);
        String urlPath = path + "/" + fileName;
        Integer uploadId = null;

        for (MultipartFile multipartFile : goodsPics) {
            try (InputStream is = multipartFile.getInputStream();
                 InputStream is2 = multipartFile.getInputStream()) {
                String error = UploadMD5Util.readZipFile(is);
                if ("error".equals(error)) {
                    throw new CallBackException(
                            AudienceValidateException.ErrorCode.AUDIENCE_upload_check_err.getValue()
                            , AudienceValidateException.ErrorCode.AUDIENCE_upload_check_err.getDesc()
                    );
                }
                String Md5Str = UploadMD5Util.getInputStreamMD5String(is2);
                if (Md5Str != null) {
                    UploadResource uploadResource = uploadResourceService.getUploadResourceMd5(Md5Str);
                    if (uploadResource == null) {
                        multipartFile.transferTo(file);
                        // 上传到本地upload
                        UploadResource uploadResources = new UploadResource();
                        uploadResources.setUrl(relativePath);
                        uploadResources.setMd5(Md5Str);
                        uploadResources.setType(UploadResourceType.UPLOAD_RESOURCE_TYPE_OTHER.getValue());
                        uploadResources.setFileName(urlPath);
                        uploadResourceService.insert(uploadResources);
                        uploadId = uploadResources.getId();

                    } else {
                        relativePath = uploadResource.getUrl();
                        uploadId = uploadResource.getId();
                        urlPath = uploadResource.getFileName();
                    }
                } else {
                    throw new CallBackException(AudienceValidateException.ErrorCode.AUDIENCE_upload_err.getValue()
                            , AudienceValidateException.ErrorCode.AUDIENCE_upload_err.getDesc());
                }
                break;
            }catch (Exception e) {
                throw new CallBackException(AudienceValidateException.ErrorCode.AUDIENCE_upload_check_err.getValue()
                        , AudienceValidateException.ErrorCode.AUDIENCE_upload_check_err.getDesc());
            }
        }

        Map<String, String> param = new HashMap<>();
        param.put("relativePath", relativePath);
        param.put("path", urlPath);
        param.put("uploadId", String.valueOf(uploadId));
        return RestfulJsonModelAndView.buildJsonModelAndView(param);
    }


    /**
     * 创建自定义人群
     *
     * @param addAudienceVo
     * @return
     */
    @RequestMapping(value = "/addAudience", method = {RequestMethod.POST})
    public ModelAndView addAudience(@RequestBody AddAudienceVo addAudienceVo, HttpSession session) throws ParamValidateException,IOException{

        Integer advertiserId = getLoginUser(session) != null ? getLoginUser(session).getAdvertiserId() : null;
        // 查询代理商id
        //Integer agentId = getLoginUser(session) != null ? getLoginUser(session).getAgentId() : null;
        if (null != advertiserId) {
            addAudienceVo.setAdvertiserId(advertiserId);
        }

        addAudienceVo.setAccountId(Integer.parseInt(accountId));
        //广告主权限
        if (null == advertiserId || 0 == advertiserId) {
            advertiserId = addAudienceVo.getAdvertiserId();
        }
        AdvertiserPlatformAudit advertiserPlatformAudit
            = advertiserPlatformAuditService.selectAdvertiserPlatformAuditByPlatformIdAndAdvertiserId(Constant.PLATFORM_ID_TENCENT,advertiserId);
        if(null == advertiserPlatformAudit) {
            throw new ParamValidateException(Result.ERR_INVALID_PARAMETER,"","广告主未审核通过");
        }
        addAudienceVo.setAdvertiserIdMarking(advertiserPlatformAudit.getPlatformAdvertiserId());
        //代理商权限
        this.validateAdvertiserParam(addAudienceVo);
        audienceService.addAudience(addAudienceVo);
        return RestfulJsonModelAndView.buildJsonModelAndView();
    }

    /**
     * 删除人群接口(自定义人群，相似人群)
     *
     * @param removeAudienceVo
     * @return
     */
    @RequestMapping(value = "/removeAudience", method = {RequestMethod.PUT})
    public ModelAndView removeAudience(@RequestBody RemoveAudienceVo removeAudienceVo) {
        int audienceLikeResult = audienceLikeService.countAudienceLike(removeAudienceVo.getId());
        // 查询是否被定向包选定
        List<String> customAudienceList = targetPackageService.customAudienceString();
        boolean state = false;
        for (String customAudience : customAudienceList) {
            String a[] = customAudience.split(",");
            for (String result : a) {
                if (result.equals(String.valueOf(audienceLikeResult))) {
                    state = true;
                }
            }
        }
        if (audienceLikeResult == 0 && !state) {
            audienceService.removeAudience(removeAudienceVo);
        }
        return RestfulJsonModelAndView.buildJsonModelAndView();
    }

    /**
     * 人群参数验证
     * @param addAudienceVo
     */
    public  void validateAdvertiserParam(AddAudienceVo addAudienceVo)throws ParamValidateException,
            UnsupportedEncodingException {
        //名称是否唯一
        int count = audienceService.countName(addAudienceVo.getName(),addAudienceVo.getAdvertiserId(),null);
        if (count != 0) {
            throw new CallBackException(AudienceValidateException.ErrorCode.AUDIENCE_NAME_NOT_NULL.getValue()
                    , AudienceValidateException.ErrorCode.AUDIENCE_NAME_NOT_NULL.getDesc());
        }
        //人群名称必填
        if(StringUtils.isEmpty(addAudienceVo.getName())){
            throw new ParamValidateException(Result.ERR_MISS_PARAMETER, "crowdName", "Result.err.miss.parameter");
        }
        //名称长度限制
        if (ValidateUtil.checkStrByteLengthLessThan(addAudienceVo.getName(), ParamConstant.CROWD_NAME_LENGTH_MIN)
                || ValidateUtil.checkStrByteLengthMoreThan(addAudienceVo.getName(), ParamConstant.CROWD_NAME_LENGTH_MAX)) {
            throw new ParamValidateException(Result.ERR_INVALID_LENGTH, "crowdName", "Result.err.invalid.length");
        }
        //描述最大长度
        if (ValidateUtil.checkStrByteLengthMoreThan(addAudienceVo.getDescription(),ParamConstant.CROWD_DESCRIPTION_LENGTH_MAX)){
            throw new ParamValidateException(Result.ERR_INVALID_LENGTH, "crowdDescription", "Result.err.invalid.length");
        }
        //上传路径必填
        if(StringUtils.isEmpty(addAudienceVo.getPath())){
            throw new ParamValidateException(Result.ERR_MISS_PARAMETER, "path", "Result.err.miss.parameter");
        }
        //号码包类型必填
        if(StringUtils.isEmpty(String.valueOf(addAudienceVo.getAdvertiserId()))){
            throw new ParamValidateException(Result.ERR_MISS_PARAMETER, "advertiserId", "Result.err.miss.parameter");
        }
        if (StringUtils.isEmpty(addAudienceVo.getCodeNumType())) {
            throw new ParamValidateException(Result.ERR_MISS_PARAMETER, "codeNumType", "Result.err.miss.parameter");
        }
        if (StringUtils.isEmpty(addAudienceVo.getPath())) {
            throw new ParamValidateException(Result.ERR_MISS_PARAMETER, "path", "Result.err.miss.parameter");
        }
    }

}
